home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Modules
/
eulinda.em
< prev
next >
Wrap
Lisp/Scheme
|
1992-10-06
|
5KB
|
187 lines
;; A simple Linda implementation
;; RJB March 92
;; (make-linda-pool)
;; (linda-out pool tag . values)
;; (linda-in pool tag . pattern)
;; (linda-read pool tag . pattern)
;; (linda-eval fun . args)
;; the pattern (? var) matches anything, and assigns that value to var
;; the pattern ? matches anything, and discards the value
;; tags, and any other patterns are matched literally
;; e.g.
;; (setq pp (make-linda-pool))
;; (linda-out pp 'foo 1 2)
;; (linda-read pp 'foo ? (? x)) setqs x to 2
;; (linda-read pp 'foo 1 2 3) suspends
(defmodule eulinda (standard0) ()
(deflocal trace-linda-p ())
(defun tril (x) (setq trace-linda-p x))
(defstruct linda-pool ()
((lock initform (make-semaphore)
accessor linda-pool-lock)
(tuple-table initform (make-linda-tuple-table)
accessor linda-pool-tuple-table))
constructor make-linda-pool)
(defun print-linda-pool (pool)
(format t "#< ")
(map-table
(lambda (k v) (format t "~a " v))
(linda-pool-tuple-table pool))
(format t ">~%"))
(defmacro linda-in (pool tag . pattern)
`(let ((*tuple* (convert (linda-tuple-value
(linda-in-primitive ,pool ,tag
,@(tidy-pattern pattern)))
vector)))
,@(do-setqs pattern)
*tuple*))
(defun tidy-pattern (pat)
(cond ((null pat) ())
((eq (car pat) '?)
(cons '? (tidy-pattern (cdr pat))))
((and (consp (car pat))
(eq (caar pat) '?))
(cons '? (tidy-pattern (cdr pat))))
(t (cons (car pat) (tidy-pattern (cdr pat))))))
(defun do-setqs-aux (pattern n)
(cond ((null pattern) ())
((and (consp (car pattern))
(eq (caar pattern) '?))
(cons `(setq ,(cadar pattern) (vector-ref *tuple* ,n))
(do-setqs-aux (cdr pattern) (+ n 1))))
(t (do-setqs-aux (cdr pattern) (+ n 1)))))
(defun do-setqs (pattern)
(do-setqs-aux pattern 0))
(defun linda-in-primitive (pool tag . pattern)
(when trace-linda-p (format t ";; in-ing ~a ~a~%" tag pattern))
(let ((val (linda-in/read pool tag (tuple tag pattern) in-match)))
(when trace-linda-p
(format t ";; in'd ~a~%" val))
val))
(defmacro linda-read (pool tag . pattern)
`(let ((*tuple* (convert (linda-tuple-value
(linda-read-primitive ,pool ,tag
,@(tidy-pattern pattern)))
vector)))
,@(do-setqs pattern)
*tuple*))
(defun linda-read-primitive (pool tag . pattern)
(when trace-linda-p (format t ";; reading ~a ~a~%" tag pattern))
(let ((val (linda-in/read pool tag (tuple tag pattern) read-match)))
(when trace-linda-p
(format t ";; read ~a~%" val))
val))
(defun linda-in/read (pool tag pattern matchfn)
(let ((lock (linda-pool-lock pool)))
(open-semaphore lock)
(let ((match (matchfn pool tag pattern)))
(close-semaphore lock)
(if (null match)
(progn
(when trace-linda-p
(format t ";; suspending~%"))
(thread-reschedule)
(when trace-linda-p
(format t ";; retrying ~a ~a~%" tag
(linda-tuple-value pattern)))
(linda-in/read pool tag pattern matchfn))
match))))
(defun linda-out (pool tag . rest)
(when trace-linda-p (format t ";; out ~a ~a~%" tag rest))
(let ((lock (linda-pool-lock pool))
(tup (tuple tag rest)))
(open-semaphore lock)
(linda-tuple-out pool tag tup)
(close-semaphore lock)
(thread-reschedule)
tup))
(defun make-linda-tuple-table ()
(make-table equal))
(defstruct linda-tuple ()
((tag initarg tag
reader linda-tuple-tag)
(value initarg value
reader linda-tuple-value))
constructor (tuple tag value))
(defmethod generic-write ((lt linda-tuple) s)
(format s "#<linda-tuple: ~a ~a>"
(linda-tuple-tag lt)
(linda-tuple-value lt)))
(defmethod generic-prin ((lt linda-tuple) s)
(format s "#<linda-tuple: ~a ~a>"
(linda-tuple-tag lt)
(linda-tuple-value lt)))
(defun delete1 (obj lis)
(cond ((null lis) ())
((eq obj (car lis)) (cdr lis))
(t (cons (car lis) (delete1 obj (cdr lis))))))
(defun in-match (pool tag pattern-tuple)
(let* ((table (linda-pool-tuple-table pool))
(vallist (table-ref table tag))
(val (match-in-list (linda-tuple-value pattern-tuple) vallist)))
(unless (null val)
((setter table-ref) table tag (delete1 val vallist)))
val))
(defun read-match (pool tag pattern-tuple)
(let* ((table (linda-pool-tuple-table pool))
(vallist (table-ref table tag)))
(match-in-list (linda-tuple-value pattern-tuple) vallist)))
(defun match-in-list (pat vallist)
(cond ((null vallist) ())
((matchit pat (linda-tuple-value (car vallist))) (car vallist))
(t (match-in-list pat (cdr vallist)))))
(defun matchit (pat val)
(cond ((null pat) t)
((null val) ())
((equal (car pat) (car val))
(matchit (cdr pat) (cdr val)))
((eq (car pat) '?)
(matchit (cdr pat) (cdr val)))
(t ())))
(defun linda-tuple-out (pool tag tuple)
(let* ((table (linda-pool-tuple-table pool))
(val (table-ref table tag)))
((setter table-ref) table tag (nconc val (list tuple)))
tuple))
(defun linda-eval (fun . args)
(apply thread-start (make-thread fun) args))
; a convenient fiddle
(defconstant ? '?)
(export make-linda-pool linda-in linda-read linda-out linda-eval)
(export linda-in-primitive linda-read-primitive)
(export linda-tuple-value ?)
(export print-linda-pool tril)
)